package com.demo.agent.tool;


import arthas.VmTool;
import com.demo.agent.MyAgent;
import com.demo.agent.manager.RegistryManager;
import com.demo.agent.tool.jad.Jad;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: huangjiazhen
 * @create: 2023/11/22 10:22
 * @description:
 **/
public class ToolServiceImpl extends UnicastRemoteObject implements ToolService {
    public ToolServiceImpl() throws RemoteException {
    }

    @Override
    public void func(String name) throws RemoteException {
        ClassLoader classLoader = this.getClass().getClassLoader();
        List<Class> collect = Arrays.stream(MyAgent.instrumentation.getInitiatedClasses(classLoader))
                .filter(s -> s.getName().toUpperCase().contains(name.toUpperCase()))
                .collect(Collectors.toList());
        collect.stream().forEach(System.out::println);
        for (Class c : collect) {

            long objectSize = MyAgent.instrumentation.getObjectSize(c);
            System.out.println(c + " : " + objectSize);
        }
        VmTool instance = VmTool.getInstance();
        Object[] instances = instance.getInstances(collect.get(0));
        System.out.println("====instances: " + instances);
        Arrays.stream(instances)
                .forEach(x -> {
                    System.out.println(x + " : " + instance.getInstanceSize(x));
                });
    }

    @Override
    public String findClassName(String name) throws RemoteException {
        System.out.println("name: " + name);
        String result = Arrays.stream(MyAgent.instrumentation.getAllLoadedClasses())
                .filter(s -> s.getName().toUpperCase().contains(name.toUpperCase()))
                .limit(20)
                .map(Class::getName)
                .collect(Collectors.joining("\r\n"));
        return result;
    }

    @Override
    public String jadClass(String className) throws RemoteException {
        System.out.println("className: " + className);
        try {
            return Jad.decompiler(className);
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    @Override
    public void exit() throws RemoteException {
        final int port = 9527;
        System.out.println("==========service: " + this);
        try {
            // 解绑服务，并注销
            Registry registry = RegistryManager.getValue(port);
            System.out.println("==========registry: " + registry);
            Naming.unbind("rmi://localhost:9527/toolService");
            UnicastRemoteObject.unexportObject(registry, true);
        }  catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
